﻿/**

 * Copyright (c) 2015-2016, FastDev 刘强 (fastdev@163.com) & Quincy.

 *

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *      http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

using ConsoleApplication1.Cluster.Entity;
using OF.DistributeService.Core.Common;
using OF.Notify.Channel;
using OF.Notify.DataHost;
using OF.Notify.DataHost.Cluster;
using OF.Notify.DataHost.Cluster.Entity;
using OF.Notify.Entity;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace OF.Notify.Master
{
    public class DataNodeProxy
    {
        internal short id = -1;
        internal int seq = -1;
        internal string url = null;

        internal INotifyService notifyService = null;

        private static ConcurrentDictionary<string, int> callCount = new ConcurrentDictionary<string, int>();

        private static void IncCallCount(string name)
        {
            if (ClusterContext.enableCountApiCall)
            {
                if (callCount.ContainsKey(name))
                {
                    callCount[name] = callCount[name] + 1;
                }
                else
                {
                    callCount[name] = 1;
                }
            }
        }

        public static ConcurrentDictionary<string, int> GetCallCount()
        {
            return callCount;
        }

        internal DataNodeProxy(short id, string url, int seq)
        {
            this.id = id;
            this.seq = seq;
            this.url = url;
            notifyService = ClusterContext.Get().GetNotifyServiceProvider().GetNotifyService(this);
        }

        public int GetSeq()
        {
            return this.seq;
        }

        public string GetUrl()
        {
            return this.url;
        }

        public short GetId()
        {
            return this.id;
        }

        public static DataNodeProxy Parse(string str)
        {
            string[] strArr = str.Split('|');
            return new DataNodeProxy(short.Parse(strArr[0]), HttpUtility.UrlDecode(strArr[1]), int.Parse(strArr[2]));
        }

        public CallServiceResult<bool> DeliverMessage(DeliverMessageRequest request)
        {
            IncCallCount("DeliverMessage");
            try
            {
                return notifyService.DeliverMessage(request);
            }
            catch (Exception ex)
            {
                Util.LogException("DeliverMessage", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<bool> SendMessage(SendMessageRequest request)
        {
            IncCallCount("SendMessage");
            try
            {
                return notifyService.SendMessage(request);
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public AllNodesRuntimeData GetAllRuntimeData(GetAllRuntimeDataRequest request)
        {
            return notifyService.GetAllRuntimeData(request);
        }

        public NodeRuntimeData GetRuntimeData(GetRuntimeDataRequest request)
        {
            return notifyService.GetRuntimeData(request);
        }


        public CallServiceResult<bool> MockDisposeAllCluster()
        {
            try
            {
                return notifyService.MockDisposeAllCluster();
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<bool> SendInstantCollectionFinished(SendInstantCollectionFinishedRequest request)
        {
            IncCallCount("SendInstantCollectionFinished");
            try
            {
                return notifyService.SendInstantCollectionFinished(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendInstantCollectionFinished", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<Dictionary<byte, IdTreeNode>> GetProcessedTreeForRestore(GetProcessedTreeForRestoreRequest request)
        {
            IncCallCount("GetProcessedTreeForRestore");
            try
            {
                return notifyService.GetProcessedTreeForRestore(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("GetProcessedTreeForRestore", ex);
                return CallServiceResult<Dictionary<byte, IdTreeNode>>.GetError(1, ex.ToString());
            }
        }


        public CallServiceResult<bool> SendInstantProcessCollection(SendInstantProcessCollectionRequest request)
        {
            IncCallCount("SendInstantProcessCollection");
            try
            {
                return notifyService.SendInstantProcessCollection(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendInstantProcessCollection", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<bool> SendDisposeOnlineCollection(SendDisposeOnlineCollectionRequest request)
        {
            IncCallCount("SendDisposeOnlineCollection");
            try
            {
                return notifyService.SendDisposeOnlineCollection(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendDisposeOnlineCollection", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<List<KeyValuePair<int, List<SmallValue16AndFlag>>>> SendGetClusterNodeChangeToNotifyData(SendGetClusterNodeChangeToNotifyDataRequest request)
        {
            IncCallCount("SendGetClusterNodeChangeToNotifyData");
            try
            {
                return notifyService.SendGetClusterNodeChangeToNotifyData(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendGetClusterNodeChangeToNotifyData", ex);
                return CallServiceResult<List<KeyValuePair<int, List<SmallValue16AndFlag>>>>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<bool> SendSaveClusterNodeChangeToNotify(SendSaveClusterNodeChangeToNotifyRequest request)
        {
            IncCallCount("SendSaveClusterNodeChangeToNotify");
            try
            {
                return notifyService.SendSaveClusterNodeChangeToNotify(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<bool> SendGetClusterNodeChangeToNotifyCmd(SendGetClusterNodeChangeToNotifyCmdRequest request)
        {
            IncCallCount("SendGetClusterNodeChangeToNotifyCmd");
            try
            {
                return notifyService.SendGetClusterNodeChangeToNotifyCmd(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<List<SmallValue16AndFlag>> SendUpdateClusterNodes(SendUpdateClusterNodesRequest request)
        {
            IncCallCount("SendUpdateClusterNodes");
            try
            {
                return notifyService.SendUpdateClusterNodes(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<List<SmallValue16AndFlag>>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<bool> SendSyncCollectionCmd(SendSyncCollectionCmdRequest request)
        {
            IncCallCount("SendSyncCollectionCmd");
            try
            {
                return notifyService.SendSyncCollectionCmd(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<bool> SendSyncCollectionData(SendSyncCollectionDataRequest request)
        {
            IncCallCount("SendSyncCollectionData");
            try
            {
                return notifyService.SendSyncCollectionData(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<bool> SendAssignOnLineClusterNodes(SendAssignOnLineClusterNodesRequest request)
        {
            IncCallCount("SendAssignOnLineClusterNodes");
            try
            {
                return notifyService.SendAssignOnLineClusterNodes(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<SendGetUnProcessedFinishedCollectionsDTO> SendGetUnProcessedFinishedCollections(SendGetUnProcessedFinishedCollectionsRequest request)
        {
            IncCallCount("SendGetUnProcessedFinishedCollections");
            try
            {
                return notifyService.SendGetUnProcessedFinishedCollections(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<SendGetUnProcessedFinishedCollectionsDTO>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<List<int>> SendProcessCollections(SendProcessCollectionsRequest request)
        {
            IncCallCount("SendProcessCollections");
            try
            {
                return notifyService.SendProcessCollections(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<List<int>>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<bool> SendSyncProcessedTree(SendSyncProcessedTreeRequest request)
        {
            IncCallCount("SendSyncProcessedTree");
            try
            {
                return notifyService.SendSyncProcessedTree(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }

        public CallServiceResult<bool> SendAssignOnlineCollection(SendAssignOnlineCollectionRequest request)
        {
            IncCallCount("SendAssignOnlineCollection");
            try
            {
                return notifyService.SendAssignOnlineCollection(request).Result;
            }
            catch (Exception ex)
            {
                Util.LogException("SendSaveClusterNodeChangeToNotify", ex);
                return CallServiceResult<bool>.GetError(1, ex.ToString());
            }
        }
    }
}
